"""
AI分析服务模块
负责与AI模型交互，进行需求分析和测试用例生成
"""

import os
import logging
import time
import asyncio
from concurrent.futures import ThreadPoolExecutor
from typing import Dict, Any, Optional
from openai import AsyncOpenAI
import httpx

from ..core.config import settings
from ..core.prompts import get_prompt, get_system_prompt

logger = logging.getLogger(__name__)


class AIService:
    """AI分析服务类"""
    
    def __init__(self):
        self.client = self._get_ai_client()
        self.max_retries = 3
        self.retry_delay = 10
        # 创建线程池用于并发处理
        self.thread_pool = ThreadPoolExecutor(max_workers=4)
    
    def _get_ai_client(self) -> AsyncOpenAI:
        """获取AI客户端实例"""
        try:
            # 创建自定义的 httpx 客户端，设置较长的超时时间
            timeout = httpx.Timeout(
                connect=60.0,
                read=300.0,
                write=60.0,
                pool=60.0
            )
            
            api_key = settings.OPENAI_API_KEY
            if not api_key:
                logger.error("未找到API密钥，请检查环境变量配置")
                raise ValueError("缺少API密钥配置")
            
            client = AsyncOpenAI(
                base_url=settings.OPENAI_BASE_URL,
                api_key=api_key,
                http_client=httpx.AsyncClient(
                    timeout=timeout,
                    transport=httpx.AsyncHTTPTransport(retries=3)
                )
            )
            
            logger.info("已创建OpenAI客户端")
            return client
        except Exception as e:
            logger.error(f"初始化AI客户端失败: {str(e)}")
            raise
    
    async def analyze_requirement(self, text: str) -> Dict[str, Any]:
        """分析需求文档，识别模糊点和风险"""
        if not text or not text.strip():
            return {
                "success": False,
                "error": "需求文本不能为空",
                "analysis": "请提供需求文档内容进行分析。"
            }
        
        try:
            # 从配置文件获取提示词
            prompt = get_prompt("requirement_analysis", requirement_text=text)
            return await self._call_ai_with_retry(prompt, "requirement_analysis")
        except ValueError as e:
            logger.error(f"提示词配置错误: {str(e)}")
            return {
                "success": False,
                "error": f"提示词配置错误: {str(e)}",
                "analysis": "系统配置错误，请联系管理员。"
            }
    
    async def generate_test_cases(self, text: str) -> Dict[str, Any]:
        """基于需求生成测试用例"""
        if not text or not text.strip():
            return {
                "success": False,
                "error": "需求文本不能为空",
                "test_cases": "请提供需求文档内容以生成测试用例。"
            }
        
        try:
            # 从配置文件获取提示词
            prompt = get_prompt("test_case_generation", requirement_text=text)
            return await self._call_ai_with_retry(prompt, "test_case_generation")
        except ValueError as e:
            logger.error(f"提示词配置错误: {str(e)}")
            return {
                "success": False,
                "error": f"提示词配置错误: {str(e)}",
                "test_cases": "系统配置错误，请联系管理员。"
            }
    
    def review_code(self, code_content: str) -> Dict[str, Any]:
        """代码审查"""
        if not code_content or not code_content.strip():
            return {
                "success": False,
                "error": "代码内容不能为空",
                "review": "请提供代码内容进行审查。"
            }
        
        try:
            # 从配置文件获取提示词
            prompt = get_prompt("code_review", code_content=code_content)
            return self._call_ai_with_retry(prompt, "code_review")
        except ValueError as e:
            logger.error(f"提示词配置错误: {str(e)}")
            return {
                "success": False,
                "error": f"提示词配置错误: {str(e)}",
                "review": "系统配置错误，请联系管理员。"
            }
    
    def generate_api_documentation(self, api_info: str) -> Dict[str, Any]:
        """生成API文档"""
        if not api_info or not api_info.strip():
            return {
                "success": False,
                "error": "API信息不能为空",
                "documentation": "请提供API信息以生成文档。"
            }
        
        try:
            # 从配置文件获取提示词
            prompt = get_prompt("api_documentation", api_info=api_info)
            return self._call_ai_with_retry(prompt, "api_documentation")
        except ValueError as e:
            logger.error(f"提示词配置错误: {str(e)}")
            return {
                "success": False,
                "error": f"提示词配置错误: {str(e)}",
                "documentation": "系统配置错误，请联系管理员。"
            }
    
    async def _call_ai_with_retry(self, prompt: str, analysis_type: str) -> Dict[str, Any]:
        """带重试机制的AI调用"""
        for attempt in range(self.max_retries):
            try:
                logger.info(f"开始AI分析，类型: {analysis_type}, 尝试次数: {attempt + 1}")
                
                response = await self.client.chat.completions.create(
                    model=settings.AI_MODEL,
                    messages=[
                        {"role": "system", "content": get_system_prompt()},
                        {"role": "user", "content": prompt}
                    ],
                    max_tokens=4000,
                    temperature=0.7
                )
                
                result_content = response.choices[0].message.content
                
                logger.info(f"AI分析完成，类型: {analysis_type}")
                
                # 根据分析类型返回不同的字段
                if analysis_type == "requirement_analysis":
                    return {
                        "success": True,
                        "analysis": result_content
                    }
                elif analysis_type == "test_case_generation":
                    return {
                        "success": True,
                        "test_cases": result_content
                    }
                elif analysis_type == "code_review":
                    return {
                        "success": True,
                        "review": result_content
                    }
                elif analysis_type == "api_documentation":
                    return {
                        "success": True,
                        "documentation": result_content
                    }
                else:
                    return {
                        "success": True,
                        "result": result_content
                    }
                
            except Exception as e:
                logger.error(f"AI分析失败 (尝试 {attempt + 1}/{self.max_retries}): {str(e)}")
                
                if attempt < self.max_retries - 1:
                    logger.info(f"等待 {self.retry_delay} 秒后重试...")
                    time.sleep(self.retry_delay)
                else:
                    error_msg = f"AI分析失败，已重试 {self.max_retries} 次: {str(e)}"
                    logger.error(error_msg)
                    
                    # 根据分析类型返回不同的错误响应
                    if analysis_type == "requirement_analysis":
                        return {
                            "success": False,
                            "error": error_msg,
                            "analysis": "AI服务暂时不可用，请稍后重试。"
                        }
                    elif analysis_type == "test_case_generation":
                        return {
                            "success": False,
                            "error": error_msg,
                            "test_cases": "AI服务暂时不可用，请稍后重试。"
                        }
                    elif analysis_type == "code_review":
                        return {
                            "success": False,
                            "error": error_msg,
                            "review": "AI服务暂时不可用，请稍后重试。"
                        }
                    elif analysis_type == "api_documentation":
                        return {
                            "success": False,
                            "error": error_msg,
                            "documentation": "AI服务暂时不可用，请稍后重试。"
                        }
                    else:
                        return {
                            "success": False,
                            "error": error_msg,
                            "result": "AI服务暂时不可用，请稍后重试。"
                        }


# 创建AI服务实例
ai_service = AIService() 